1550. Битовые уравнения

 

  Вам заданы два натуральных числа x и k. Найдите k-ое наименьшее натуральное решение y (значение k считается с 1) следующего уравнения:

x + y = x | y

Через '|' здесь обозначена побитовая операция OR.

 

Вход. Каждая строка является отдельным тестом и содержит два целых числа x и k (1 ≤ x, k ≤ 2*109).

 

Выход. Для каждого теста в отдельной строке вывести k-ое наименьшее натуральное решение y выше приведенного уравнения.

 

Пример входа

5 1

5 5

10 3

1 1000000000

 

Пример выхода

2

18

5

2000000000

 

 

РЕШЕНИЕ

математика

 

Анализ алгоритма

Значение y будет решением уравнения тогда и только тогда, когда y имеет нули в тех позициях, в которых в x стоят единицы. Например, если x = 10011010012 = 61710, то последние 10 цифр y должны быть 0**00*0**0, где ‘*’ обозначает 0 или 1. Любая замена звездочек на 0 или 1 дает решение. Наименьшим будет решение, когда звездочки будут заменены на 00001, то есть y = 0000000010 = 102 = 210,  x + y = x | y = 10011010112 = 61910. Второе наименьшее решение получится, если звездочки заменить на 00010, третье – если на 00011 и так далее.

k - ое наименьшее положительное целое решение уравнения можно получить, если звездочки заменить на двоичное представление числа k.

 

Реализация алгоритма

Функция kthPlusOrSolution возвращает k - ое наименьшее натуральное решение уравнения.

 

long long kthPlusOrSolution(long long x, long long k)

{

  long long pos, y = 0;

  for(pos = 0; k; pos++)

  {

 

Если в бинарном представлении числа x в позиции pos стоит 1, то в y на этой позиции должен находиться 0.

 

    if (x >> pos & 1) continue;

 

В позицию pos результата y заносим последний бит числа k. Далее делим k на 2, таким образом перебирая все биты его двоичного представления.

 

    if (k % 2) y = y | (1LL << pos);

    k /= 2;

  }

  return y;

}

 

Основная часть программы.

 

while(scanf("%lld %lld",&x,&k) == 2)

{

  res = kthPlusOrSolution(x,k);

  printf("%lld\n",res);

}